package com.ttx.pattern.example.composite.after;

import java.util.*;

/**
 * 组合节点， 拥有子节点
 * @author TimFruit
 * @date 2019/7/8 15:44
 */

public class Composite extends Component {
    private List<Component> components=new ArrayList<>();
    private String name;

    public Composite(String name) {
        this.name = name;
    }

    @Override public void add(Component component) {
        this.components.add(component);
    }

    @Override public void remove(Component component) {
        this.components.remove(component);
    }

    @Override
    public Component getChild(int i){
        return this.components.get(i);
    }
    
    @Override public Collection<Component> getChildren() {
        return this.getChildren();
    }

    @Override public String getName() {
        return this.name;
    }

    @Override public Iterator<Component> iterator() {
        return new CompositeIterator(this.components.iterator());
    }

    @Override public void operation() {
        System.out.println("composite: "+name);
    }

    private class CompositeIterator implements Iterator<Component>{
        
        private Stack<Iterator<Component>> stack=new Stack<>();

        public CompositeIterator(Iterator<Component> iterator) {
            this.stack.push(iterator);
        }

        // 表示是否有子节点
        @Override public boolean hasNext() {
            if(stack.isEmpty()){
                return false;
            }
            Iterator<Component> iter=stack.peek();
            if(!iter.hasNext()){
                stack.pop();
                return hasNext();
            }else {
                return true;
            }
        }

        @Override public Component next() {
            if(!hasNext()){
                return null;
            }
            Iterator<Component> iter=stack.peek();
            Component component=iter.next();
            if(component instanceof  Composite) {
                stack.push(component.iterator());    //类似深度优先搜索 
            }
            return component;
        }
    }
    
}
